; codigo_t *generar_tabla_codigos ( unsigned int *tabla_apariciones )

%include "macros.mac"
extern generar_codigo
%include "crear_lista_huffman.asm"

extern crear_arbol_huffman
;~extern crear_lista_huffman
%include "borrar_arbol.asm"
extern calloc
extern printf

%define tabla_apariciones	[ebp + 8]

%define ptr_tabla_codigos	[ebp - 4]
%define ptr_tabla_nodos		[ebp - 8]
%define ptr_lista_huff		[ebp - 12]
%define ptr_arbol_huff		[ebp - 16]

%define sizeof_uint		4
%define sizeof_codigo_t	16
%define sizeof_ptr_nodo_arbol	4	

%macro esNULLTablaNodos_i 1
cmp [esi + %1 * sizeof_ptr_nodo_arbol], dword 0
%endmacro

%macro TablaNodos_i 1
	push dword [esi + %1 * sizeof_ptr_nodo_arbol]
%endmacro

%macro SalvarRegNoConvencionC 0
	push eax
	push ecx
	push edx
%endmacro

%macro RestaurarRegNoConvencionC 0
	pop edx
	pop ecx
	pop eax
%endmacro


global generar_tabla_codigos



section .data

msg_error	db "Error al comprimir: el codigo supera los 32 bits.",10,0




section .text

generar_tabla_codigos:
						convencion_C 16
						

	; Reservo memoria para la tabla de codigos
						push dword sizeof_codigo_t
						push dword 256
						call calloc
						add esp, 8

						
						mov ptr_tabla_codigos, eax		; lo resguardo
						
						
	; Reservo memoria para la tabla con punteros a nodos arbol
						push dword sizeof_ptr_nodo_arbol
						push dword 256
						call calloc
						add esp, 8
						
						mov ptr_tabla_nodos, eax		; lo resguardo
						
						; Inicializo una variable local, como param para crear_lista_huffman
						mov ptr_lista_huff, dword 0
						lea edx,ptr_lista_huff
						
	; Creo lista de Huffman
						mov esi,tabla_apariciones
						SalvarRegNoConvencionC	
						push eax				; tabla de punteros a las hojas
						push edx				; puntero a la lista
						push esi				; tabla de apariciones
						call crear_lista_huffman
						add esp, 12
						RestaurarRegNoConvencionC
						
						
						mov ptr_arbol_huff, dword 0
						lea eax, ptr_arbol_huff
						lea edx, ptr_lista_huff
						
						;~lea edx, ptr_lista_huff
	; Creo arbol de Huffman
						SalvarRegNoConvencionC					
						push eax				; puntero al arbol
						push edx				; puntero a la lista
						call crear_arbol_huffman
						add esp, 8
						RestaurarRegNoConvencionC
						
	; Genero la codificacion de cada caracter de la tabla usando el arbol de huffman
						mov ecx, 0			; i = 0
						mov eax, 0			; codigo de error
						
						mov edi, ptr_tabla_codigos
						mov esi, ptr_tabla_nodos
						mov ebx, ptr_arbol_huff
			
			.cicloFor:
						esNULLTablaNodos_i ecx		; ¿ tabla_nodos[i] == NULL?
						jz .avanzar
									
									push ecx
									
									push edi			; tabla_codigos[i]
									push dword [esi + ecx * sizeof_ptr_nodo_arbol]	; tabla_nodos[i]
									push ebx			; ptr_arbol_huffman
									call generar_codigo
									add esp, 12
									
									pop ecx

									cmp eax, 0		; codigo de error == 0
									jnz .avanzar
									
									
									;Si ocurrio un error

									
									
									push msg_error
									call printf
									add esp, 4
									mov eax,0
									jmp .fin
									
									
						
						
			.avanzar:	inc ecx
						add edi, sizeof_codigo_t			;  ptr_tabla_de_codigos++

						cmp ecx, 256
						je .finFor

						jmp .cicloFor
												

	; Libero memoria usada por el arbol de huffman
			.finFor:	mov eax, ptr_arbol_huff
						push dword eax
						call borrar_arbol
						add esp, 4

						

	; Devuelvo la tabla de codigos por eax		
			.fin:
				push dword ptr_tabla_nodos
				call free
				add esp,4
				
				mov eax, ptr_tabla_codigos
						
						
						convencion_C_fin 16
						ret
